#include <QTableView>
#include <QHeaderView>
#include <QAbstractTableModel>
#include <QItemDelegate>
#include<QStyledItemDelegate>
#include <QModelIndexList>
#include <QItemSelectionModel>
#include <QPushButton>
#include <QStyle>
#include <QMouseEvent>
#include <QStringList>
#include <QPainter>
#include <QPixmap>
#include <QMap>
#include <QFont>
#include <QApplication>
#include <QScrollBar>
#include <QLabel>
#include <QProgressBar>
#include <QDebug>

class multilinetableview;
class dragtableview;
class customtablemodel;

struct uniteitem
{
    int startcolumn;
    int columncount;
    int endcolumn;
    QString strtext;
};

/********************icondelegate********************/
class icondelegate: public QStyledItemDelegate
{
public:
    icondelegate(QObject * parent = 0);
    virtual ~ icondelegate() {}

    void paint(QPainter * painter,
               const QStyleOptionViewItem & option,
               const QModelIndex & index) const;
    void setSelectIndexList(QModelIndexList selectedlist); //设置选中的index()
    void clearSelectIndexList();
    QModelIndexList getSelectIndexList();
private:
    QColor m_framecolor;
    QPixmap m_checkpixmap;
    QPixmap m_uncheckpixmap;
    QModelIndexList m_selectedlist;  //选中行列表
};

/********************pixmapdelegate********************/
class pixmapdelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit pixmapdelegate(QObject * parent = 0);
    ~pixmapdelegate();

    void paint(QPainter * painter,
               const QStyleOptionViewItem & option,
               const QModelIndex & index) const;
    bool editorEvent(QEvent * event,
                     QAbstractItemModel * model,
                     const QStyleOptionViewItem & option,
                     const QModelIndex & index);
    void setpixmaptypelist(QList<int> showtypelist);
private:
    QPixmap m_yespixmap;
    QPixmap m_nopixmap;
    QList<int> m_pixmaptypelist;
};

/********************progressbardelegate********************/
class progressbardelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit progressbardelegate(QObject * parent = 0);
    ~progressbardelegate();

    void paint(QPainter * painter,
               const QStyleOptionViewItem & option,
               const QModelIndex & index) const;
    bool editorEvent(QEvent * event,
                     QAbstractItemModel * model,
                     const QStyleOptionViewItem & option,
                     const QModelIndex & index);
public:
    QProgressBar m_paintbar;
};

/********************pushbuttondelegate********************/
class pushbuttondelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit pushbuttondelegate(QObject * parent = 0, QString itemtext = "");
    ~pushbuttondelegate();

    void paint(QPainter * painter,
               const QStyleOptionViewItem & option,
               const QModelIndex & index) const;
    bool editorEvent(QEvent * event,
                     QAbstractItemModel * model,
                     const QStyleOptionViewItem & option,
                     const QModelIndex & index);
public:
    QMap<QModelIndex, QRect> m_btnrectmap;
    QRect m_currentrect;
    bool m_bmousepressed; //鼠标左键点击按钮标识
    QString m_itemtext; //单元格内容
    QPushButton m_paintbtn;
    QColor m_btntextcolor;//自定义按钮字体颜色

signals:
    void btnClicked(int row, int column);

};

/********************colordelegate********************/
class colordelegate: public QStyledItemDelegate
{
    //功能：设置选中时单元格字体高亮颜色
    Q_OBJECT
public:
    explicit colordelegate(QWidget * parent = 0) {}
    ~colordelegate() {}
    void paint(QPainter * painter,
               const QStyleOptionViewItem & option,
               const QModelIndex & index) const
    {
        QStyleOptionViewItem viewoption(option);
        viewoption.palette.setColor(QPalette::HighlightedText, index.data(Qt::TextColorRole).value<QColor>());
        QStyledItemDelegate::paint(painter, viewoption, index);
    }
};

/********************customheaderview********************/
class customheaderview : public QHeaderView
{
    Q_OBJECT
public:
    customheaderview(Qt::Orientation orientation, QWidget * parent = 0);

protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent * event);
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;

    QRect getSectionRect(int logicalIndex) const;
    QRect getIconRect(int logicalIndex) const;
    QRect getSortIconRect(int logicalIndex) const;
    void drawIcon(QPainter *painter, int logicalIndex, QPixmap pixmap) const;
    void drawsorticon(QPainter *painter, int logicalIndex) const;
    void setCheckAll();
    void setUncheckAll();

private:
    QPixmap m_checkpixmap;
    QPixmap m_uncheckpixmap;
    QPixmap m_sortwaitpixmap;
    QPixmap m_sortascpixmap;
    QPixmap m_sortdescpixmap;
    bool m_ischeckall;  //是否全选
    int m_sortby;//当前排序方式【 1: 等待 2：升序 3：降序】
    int m_currentcolumn;  //当前选中列

protected:
    QColor m_bgcolor; //表头背景色
    QColor m_framecolor; //表头边框色

signals:
    void headerSortClicked(int sort, int column);
    void headerSelectAll();
    void headerClearSelection();
public slots:
    void headerItemClicked(int logicalIndex);
    void isCheckAll(bool ischeckall);
};

/********************dragheaderview********************/
class dragheaderview : public customheaderview
{
    Q_OBJECT
public:
    dragheaderview(Qt::Orientation orientation, dragtableview * parent = 0);
    ~dragheaderview(void);

private:
    dragtableview *m_parent;
    bool m_mouselbtnpressed;
    int m_columnfrom;                 //拖动起始行
    int m_columnto;                   //拖动时(还没松开时)鼠标位置代表的行，会绘制一条指示线，类似QQ好友列表拖拽效果
    QString m_dragtext;               //拖拽过程中跟随鼠标显示的内容
    QPoint m_dragpoint;               //拖拽起点
    QLabel* m_toplabel;               //向上指示箭头
    QLabel* m_bottomlabel;            //向下指示箭头
    int m_headerheight;               //表头的高度

protected:
    void mousePressEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent * event);
    //拖拽响应事件
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dragLeaveEvent(QDragLeaveEvent *event);
    void dropEvent(QDropEvent *event);

private:
    void startDrag();
    void movecolumn();
    QColor changeColorDepth(QColor color, int value);
};

/********************multilineheaderview********************/
class multilineheaderview : public QHeaderView
{
    Q_OBJECT
public:
    multilineheaderview(Qt::Orientation orientation, multilinetableview * parent = 0);
    ~multilineheaderview(void);
    void setHorizontalHeaderList(QStringList horizontalHeaderList);
    void setUniteItems(int startcolumn, int columncount, QString strtext); //设置合并单元格：起始列与合并列数

protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent * event);
    void mouseReleaseEvent(QMouseEvent * event);
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;

    QRect getSectionRect(int logicalIndex) const;
    QRect getIconRect(int logicalIndex) const;
    QRect getSortIconRect(int logicalIndex) const;
    QRect getUniteRect(int logicalIndex) const;
    QRect getSortIconUniteRect(int logicalIndex) const;
    QRect getUniteItemsRect(int startcolumn, int endcolumn) const;
    void drawIcon(QPainter *painter, int logicalIndex, QPixmap pixmap) const;
    void drawItem(QPainter *painter, int logicalIndex) const;
    void drawUniteItem(QPainter *painter, int logicalIndex, uniteitem item) const;
    void setCheckAll();
    void setUncheckAll();

private:
    QPixmap m_checkpixmap;
    QPixmap m_uncheckpixmap;
    QPixmap m_sortwaitpixmap;
    QPixmap m_sortascpixmap;
    QPixmap m_sortdescpixmap;
    bool m_ischeckall;  //是否全选
    int m_sortby;//当前排序方式【 1: 等待 2：升序 3：降序】
    int m_currentcolumn;  //当前选中列
    QStringList m_hheaderlist;
    QMap<int, uniteitem> m_uniteitemsmap;
    QList<uniteitem> m_uniteitemslist;
    bool m_bmousepressed; //鼠标左键点击按钮标识
    int m_currentindex;
    multilinetableview *m_parent;

protected:
    QColor m_bgcolor; //表头背景色
    QColor m_framecolor; //表头边框色

signals:
    void headerSortClicked(int sort, int column);
    void headerSelectAll();
    void headerClearSelection();
    void headerClicked(int);
public slots:
    void headerItemClicked(int logicalIndex);
    void isCheckAll(bool ischeckall);
};

/********************customtablemodel********************/
class customtablemodel : public QAbstractTableModel
{
    Q_OBJECT
public:
    customtablemodel(QObject *parent = 0);
    ~customtablemodel(void);
    void setHorizontalHeaderList(QStringList horizontalHeaderList);
    void setVerticalHeaderList(QStringList verticalHeaderList);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
    void setModalDatas(QList< QStringList > *rowlist);
    void refrushModel();
    void changeHHeaderData(int frontcolumn, int tocolumn);
    void changeData(int frontcolumn, int tocolumn);

public:
    QMap<QString, QColor> m_textcolormap;

private:
    QStringList m_hheaderlist;
    QStringList m_vheaderlist;
    QList< QStringList > *m_modeldataslist;

signals:

public slots:
};

/********************tableview********************/
class tableview : public QTableView
{
    Q_OBJECT

public:
    tableview(QWidget *parent = 0);
    ~tableview(void);
    void addRow(QStringList rowList);
    int rowCount();
    int columnCount();
    void setHHeader(QStringList hheader);
    void SetItemTextColor(QString itemtext, QColor color);
    QModelIndexList getSelectedList();
    customtablemodel *getCustomTableModel();
    QList<int> getColumnIdList();
    void changeColumnWidth(int frontcolumn, int tocolumn);
    void changeDelegate(int frontcolumn, int tocolumn);
    void changeColumnId(int frontcolumn, int tocolumn);
    void setDragSelectedRows();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent * event);
    virtual bool eventFilter(QObject *, QEvent *);

signals:
    void headerSortClicked(int sort, int column);
    void btnClicked(int row, int column);
    void isCheckAll(bool ischeckall);
    void DragSelectedRows();

public slots:
    void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
    void remove();
    void clear();
    void setIconSelection(QModelIndexList selectedlist);

public:

protected:
    QList< QStringList > m_griddatalist;
    customtablemodel *m_customtablemodel;
    icondelegate *m_icondelegate;

private:
    QModelIndexList m_selectedlist;
    QColor m_selectedbgcolor; //表格选中背景色
    QList<int> m_columnidlist;
};

/********************customtableview********************/
class customtableview : public tableview
{
    Q_OBJECT

public:
    customtableview(QWidget *parent = 0);
    ~customtableview(void);

private:
    customheaderview *m_headerview;

signals:

public slots:
    void clear();

};

/********************frozentableview********************/
class frozentableview : public customtableview
{
    Q_OBJECT

public:
    frozentableview(QWidget *parent = 0);
    ~frozentableview();

private:
    bool m_mouselbtnpressed;
    QRect m_parentrect;
    QModelIndex m_mouselbtnindexpressed;//鼠标左键按下位置
    QModelIndex m_mouselbtnindexprevious;//鼠标左键上一次所在位置

protected:
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);

signals:
    void currentRowPressed(int currentrow);
    void selectionRows(int minrow, int maxrow);

private slots:
    void updateCurrentRowPressed(int currentrow);
    void updateSelectionRows(int minrow, int maxrow);
    void setParentWidgetRect(QRect parentrect);

};

/********************freezetableview********************/
class freezetableview : public customtableview
{
    Q_OBJECT

public:
    freezetableview(QWidget *parent = 0);
    ~freezetableview();
    void setFreezeColumns(int count);
    void setFreezeRowHeight(int row, int height);

private:
    bool m_mouselbtnpressed;
    QModelIndex m_mouselbtnindexpressed;//鼠标左键按下位置

protected:
    int m_freezecolumns;   //冻结列数
    frozentableview *m_frozentableview;

protected:
    virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
    virtual void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE;

private:
    void initFrozenTableView();
    void updateFrozenTableViewGeometry();

protected:
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *e);

signals:
    void currentRowPressed(int currentrow);
    void selectionRows(int minrow, int maxrow);
    void setWidgetRect(QRect parentrect);

private slots:
    void updateFrozenSectionWidth(int logicalIndex, int oldSize, int newSize);
    void updateSectionWidth(int logicalIndex, int oldSize, int newSize);
    void updateCurrentRowPressed(int currentrow);
    void updateSelectionRows(int minrow, int maxrow);
};
/********************以上是封装类，作为基类使用********************/

/********************以下是自定义类，根据需求继承基类使用************/
/********************tasktableview********************/
class tasktableview : public customtableview
{
    Q_OBJECT
public:
    tasktableview(QWidget *parent = 0);
    ~tasktableview();

public:
    pushbuttondelegate *m_progressdelegate;
    pushbuttondelegate *m_resultdelegate;
    colordelegate *m_colordelegate;
    progressbardelegate *m_progressbardelegate;
};

/********************resulttableview********************/
class resulttableview : public freezetableview
{
    Q_OBJECT
public:
    resulttableview(QWidget *parent = 0);
    ~resulttableview();

public:
    pushbuttondelegate *m_websitedelegate;
    colordelegate *m_colordelegate;
    colordelegate *m_markcolordelegate;
};

/********************dragtableview********************/
class dragtableview : public tableview
{
    Q_OBJECT
public:
    dragtableview(QWidget *parent = 0);
    ~dragtableview();
    void addDragRow(QStringList rowlist);
    void setpixmaptypelist(QList<int> showtypelist);

public:
    dragheaderview *m_headerview;
    pushbuttondelegate *m_progressdelegate;
    pushbuttondelegate *m_resultdelegate;
    colordelegate *m_colordelegate;
    pixmapdelegate *m_pixmapdelegate;

public slots:
    void clear();
};

/********************dragtableview********************/
class multilinetableview : public tableview
{
    Q_OBJECT
public:
    multilinetableview(QWidget *parent = 0);
    ~multilinetableview();
    void setpixmaptypelist(QList<int> showtypelist);
    void setHMultilineHeader(QStringList hheader);
    void setUniteItems(int startcolumn, int columncount, QString strtext); //设置合并单元格：起始列与合并列数

public:
    multilineheaderview *m_headerview;
    pushbuttondelegate *m_progressdelegate;
    pushbuttondelegate *m_resultdelegate;
    colordelegate *m_colordelegate;
    pixmapdelegate *m_pixmapdelegate;

public slots:
    void clear();
};

